package com.hzy.fivepalace.admin.service;

import cn.hutool.core.lang.Validator;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hzy.fivepalace.admin.controller.base.BaseController;
import com.hzy.fivepalace.admin.dao.AddAdminUserDto;
import com.hzy.fivepalace.admin.dao.UpdAdminUserDto;
import com.hzy.fivepalace.common.util.PwdCheckUtil;
import com.hzy.fivepalace.common.util.ResponseUtil;
import com.hzy.fivepalace.common.util.TableDataInfo;
import com.hzy.fivepalace.common.util.bcrypt.BCryptPasswordEncoder;
import com.hzy.fivepalace.db.dao.DtsAdminMapper;
import com.hzy.fivepalace.db.domain.DtsAdmin;
import com.hzy.fivepalace.db.domain.DtsAdminExample;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 后台账号管理服务
 */
@Service
public class AdminManageService extends BaseController {

    @Resource
    private DtsAdminMapper adminMapper;

    @Resource
    private Redisson redisson;

    /**
     * 获取后台管理账号列表
     *
     * @param page
     * @param size
     * @param userName
     * @return
     */
    public TableDataInfo getSysUserList(Integer page, Integer size, String userName) {
        if (!sysIsAdmin()) {
            return TableDataInfo.errorDataTable("账号无权限");
        }
        DtsAdminExample example = new DtsAdminExample();
        example.setOrderByClause("add_time desc");
        if (!StringUtils.isBlank(userName)) {
            example.createCriteria().andUsernameEqualTo(userName).andDeletedEqualTo(false);
        } else {
            example.createCriteria().andDeletedEqualTo(false);
        }
        Page p = PageHelper.startPage(page, size, true);
        List<DtsAdmin> list = adminMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        } else {
            list.forEach(item -> {
                //敏感字段置空
                item.setPassword(null);
            });
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }

    /**
     * 删除后台管理用户
     *
     * @param userId
     * @return
     */
    public Object deleteSysUser(Integer userId) {
        if (!sysIsAdmin()) {
            return ResponseUtil.fail("账号无权限");
        }
        RLock lock = redisson.getLock("admin_deleteSysUser_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent("其他管理人员操作中,请稍后再试");
        }
        lock.lock(30, TimeUnit.SECONDS);

        DtsAdmin user = adminMapper.selectByPrimaryKey(userId);
        if (null == user || user.getDeleted()) {
            lock.unlock();
            return ResponseUtil.fail("账号不存在");
        }
        if (user.getUsername().equals("admin")) {
            lock.unlock();
            return ResponseUtil.fail("无法对admin操作");
        }
        user.setDeleted(true);
        user.setUpdateTime(LocalDateTime.now());
        adminMapper.updateByPrimaryKeySelective(user);
        lock.unlock();
        return ResponseUtil.ok("删除成功", null);
    }


    /**
     * 重置后台管理用户密码
     *
     * @param newPassword
     * @param userId
     * @return
     */
    public Object resetSysUserPasswords(String newPassword, Integer userId) {
        if (!sysIsAdmin()) {
            return ResponseUtil.fail("账号无权限");
        }
        RLock lock = redisson.getLock("admin_newPassword_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent("其他管理人员操作中,请稍后再试");
        }
        lock.lock(30, TimeUnit.SECONDS);
        if (StringUtils.isBlank(newPassword)) {
            lock.unlock();
            return ResponseUtil.fail("新密码不能为空");
        }

        DtsAdmin user = adminMapper.selectByPrimaryKey(userId);
        if (null == user || user.getDeleted()) {
            lock.unlock();
            return ResponseUtil.fail("账号不存在");
        }
        if (user.getUsername().equals("admin")) {
            lock.unlock();
            return ResponseUtil.fail("无法对admin操作");
        }

        //校验密码复杂度
        String checkPwdMsg = PwdCheckUtil.checkPwd(newPassword);
        if (!StringUtils.isBlank(checkPwdMsg)) {
            //移除锁
            lock.unlock();
            return ResponseUtil.fail(checkPwdMsg);
        }
        String rawPassword = newPassword;
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encodedPassword = encoder.encode(rawPassword);
        user.setPassword(encodedPassword);
        user.setUpdateTime(LocalDateTime.now());
        adminMapper.updateByPrimaryKeySelective(user);
        lock.unlock();
        return ResponseUtil.ok("重置成功", null);
    }


    /**
     * 新增后台管理用户
     *
     * @param dto
     * @return
     */
    public Object addSysUser(AddAdminUserDto dto) {
        if (!sysIsAdmin()) {
            return ResponseUtil.fail("账号无权限");
        }
        RLock lock = redisson.getLock("admin_addSysUser");
        if (lock.isLocked()) {
            return ResponseUtil.frequent("其他管理人员操作中,请稍后再试");
        }
        lock.lock(30, TimeUnit.SECONDS);
        //入参校验
        if (StringUtils.isBlank(dto.getUserName())) {
            lock.unlock();
            return ResponseUtil.fail("账号不能为空");
        }
        if (StringUtils.isBlank(dto.getPassword())) {
            lock.unlock();
            return ResponseUtil.fail("密码不能为空");
        }
        //校验密码复杂度
        String checkPwdMsg = PwdCheckUtil.checkPwd(dto.getPassword());
        if (!StringUtils.isBlank(checkPwdMsg)) {
            //移除锁
            lock.unlock();
            return ResponseUtil.fail(checkPwdMsg);
        }

        if (!StringUtils.isBlank(dto.getPhonenumber()) && !Validator.isMobile(dto.getPhonenumber())) {
            lock.unlock();
            return ResponseUtil.fail("手机号格式错误");
        }

        //判断账号是否存在
        DtsAdminExample example = new DtsAdminExample();
        example.createCriteria().andUsernameEqualTo(dto.getUserName()).andDeletedEqualTo(false);
        int count = (int) adminMapper.countByExample(example);
        if (count > 0) {
            lock.unlock();
            return ResponseUtil.fail("账号 '" + dto.getUserName() + "' ,已存在");
        }

        DtsAdmin user = new DtsAdmin();
        String rawPassword = dto.getPassword();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encodedPassword = encoder.encode(rawPassword);
        user.setPassword(encodedPassword);
        user.setUsername(dto.getUserName());
        user.setDeleted(false);
        user.setTel(StringUtils.isBlank(dto.getPhonenumber()) ? null : dto.getPhonenumber());
        user.setAvatar(StringUtils.isBlank(dto.getAvatar()) ? null : dto.getAvatar());
        user.setDesc(StringUtils.isBlank(dto.getRemark()) ? null : dto.getRemark());
        user.setAddTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        adminMapper.insertSelective(user);
        lock.unlock();
        return ResponseUtil.ok("新增成功", null);
    }

    /**
     * 修改后台管理用户
     *
     * @param dto
     * @return
     */
    public Object updSysUser(UpdAdminUserDto dto) {
        if (!sysIsAdmin()) {
            return ResponseUtil.fail("账号无权限");
        }

        if (null == dto.getUserId() || dto.getUserId() < 1) {
            return ResponseUtil.fail("用户id为空");
        }
        RLock lock = redisson.getLock("admin_updSysUser" + dto.getUserId());
        if (lock.isLocked()) {
            return ResponseUtil.frequent("其他管理人员操作中,请稍后再试");
        }
        lock.lock(30, TimeUnit.SECONDS);

        //入参校验
        if (!StringUtils.isBlank(dto.getPhonenumber()) && !Validator.isMobile(dto.getPhonenumber())) {
            lock.unlock();
            return ResponseUtil.fail("手机号格式错误");
        }

        DtsAdmin user = adminMapper.selectByPrimaryKey(dto.getUserId());
        if (null == user || user.getDeleted()) {
            lock.unlock();
            return ResponseUtil.fail("账号不存在");
        }
        if (user.getUsername().equals("admin")) {
            lock.unlock();
            return ResponseUtil.fail("无法对admin操作");
        }

        DtsAdmin userUpd = new DtsAdmin();
        userUpd.setId(dto.getUserId());
        userUpd.setTel(StringUtils.isBlank(dto.getPhonenumber()) ? null : dto.getPhonenumber());
        userUpd.setAvatar(StringUtils.isBlank(dto.getAvatar()) ? null : dto.getAvatar());
        user.setDesc(StringUtils.isBlank(dto.getRemark()) ? null : dto.getRemark());
        user.setUpdateTime(LocalDateTime.now());
        adminMapper.updateByPrimaryKeySelective(userUpd);
        lock.unlock();
        return ResponseUtil.ok("修改成功", null);
    }
}
